home *** CD-ROM | disk | FTP | other *** search
- /* steali.c -- install and remove C-language input handler
- * Copyright (c) 1988, I and I Computing, and Commodore-Amiga, Inc.
- *
- *
- * Executables based on this information may be used in software
- * for Commodore Amiga computers. All other rights reserved.
- *
- * This information is provided "as is"; no warranties are made.
- * All use is at your own risk, and no liability or responsibility is assumed.
- */
-
- #include "sysall.h"
-
- #define TEST 0
-
- #if TEST
-
- /* Test Input Handler
- * this fellow runs as the input.device task. His context is set
- * up so that he can access global data and other functions,
- * but it must be remembered that no DOS functions may be used.
- */
- struct InputEvent *
- customHandler(input_event)
- struct InputEvent *input_event;
- {
- extern long int shared_count; /* global data */
- struct InputEvent *ie;
-
- /* count 'em */
-
- for (ie = input_event; ie; ie = ie->ie_NextEvent)
- {
- shared_count++;
- }
-
- return (input_event);
- }
-
- /* indicator variable shared by my task and my input handler */
- long int shared_count = 0;
-
- main()
- {
- LONG installInputHandler();
-
- printf("try to install my handler\n");
-
- /* install my input handler at priority greater than Intuition */
- installInputHandler( customHandler, 51);
-
- /* wait for something to happen */
- printf("handler installed, press rtc:");
- fflush(stdout);
- getchar();
-
- /* remove my fellow */
- extractInputHandler();
-
- printf("there were %ld input events counted by our handler\n", shared_count);
- }
-
- #endif TEST
-
- struct MsgPort *indev_port = NULL;
- struct IOStdReq *indev_req = NULL;
- struct Interrupt handler_interrupt;
-
- /*
- * opens input.device, installs an input handler
- * that calls c_handler in a C friendly way
- *
- * NOTE: returns WaitIO() return value, which is
- * 0 if OK.
- */
- LONG
- installInputHandler( c_handler, priority)
- struct InputEvent *(*c_handler)();
- int priority;
- {
- LONG handlerInterface(); /* asm-C interface code */
-
- indev_port = CreatePort( NULL, 0L );
- indev_req = CreateStdIO( indev_port );
-
- OpenDevice( "input.device", 0L, indev_req, 0L );
-
- /* set up interrupt struct, use C-handler address as the data */
- handler_interrupt.is_Code = (VOID (*)()) handlerInterface;
- handler_interrupt.is_Data = (APTR) c_handler;
- handler_interrupt.is_Node.ln_Pri = priority;
-
- indev_req->io_Command = IND_ADDHANDLER;
- indev_req->io_Data = (APTR) &handler_interrupt;
-
- /* install the sucker */
- SendIO( indev_req );
- return ( WaitIO( indev_req ) );
- }
-
- /*
- * better be sure that installInputHandler() worked and is
- * in effect.
- */
- extractInputHandler()
- {
- indev_req->io_Command = IND_REMHANDLER;
-
- SendIO( indev_req );
- WaitIO( indev_req );
-
- CloseDevice( indev_req ); /* close input.device */
- DeleteStdIO( indev_req );
- DeletePort( indev_port );
- }
-
- /*
- * what follows is an assembly language fragment necessary (perhaps
- * more than necessary) to call a small model Aztec C program from
- * the input device.
- *
- * Aztec C has a different register convention than the system code,
- * and small model requires that a base address pointer be set
- * up in register A4. Also, the parameter to an input handler
- * must be pushed on the stack for a C routine to use it.
- */
-
- #asm
- cseg
- public _handlerInterface
- public _geta4
-
- ; --- NEVER FORGET that this runs as the input.device task
-
- _handlerInterface:
- ; --- pointers to linked list of input events in a0, is_Data in a1
- ; --- is_Data is simply the address of the C handler
-
- ; --- protect everything necessary (and more?)
- movem.l d2/d3/d4-d7/a2-a6,-(sp)
- jsr _geta4 ; set up context for handler (Aztec C function)
- move.l a0,-(sp) ; push input event list
- jsr (a1) ; jump to real C handler
- addq.l #4,a7 ; pop argument
- movem.l (sp)+,d2/d3/d4-d7/a2-a6
-
- rts
- #endasm
-
-